#pragma once

#include <string>
#include <exception>
#include <memory>
#   define FMT_HEADER_ONLY
#if defined (__APPLE__) || defined (__linux__)
#   include <fmt/core.h>
#elif defined (_WIN32) || defined (_WIN64)
#   include "../fmt/core.h"
#endif

namespace easymysql
{

struct except : std::exception
{
    except(const std::string& s)
        : _s(s)
    {}

    virtual const char* what() const throw()
    {
        return _s.c_str();
    }

private:
    std::string _s;
};

template<typename value_type>
class optional
{
public:
    optional() = default;

    optional(value_type&& val)
        : _val(new value_type(std::move(val)))
    {}

    optional(const value_type&) = delete;
    optional& operator=(const value_type&) = delete;

    operator bool()
    {
        return !_val;
    }

    value_type& operator*()
    {
        if (!_val)
            throw std::runtime_error("has no value");

        return *_val;
    }

private:
    std::unique_ptr<value_type> _val;
};

class fmtr
{
public:
    template<typename... Args>
    static std::string format(const std::string& fmt, Args&&... args)
    {
        return fmt::format(fmt, std::forward<Args>(args)...);
    }

};

} // namespace easymysql
